package com.st.api.util;

import java.io.IOException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Http连接池单例工具类
 * 
 * @author wuxianwei
 *
 */
public class HttpClientUtils {

	private HttpClientUtils() {
	}
	
	private static HttpClientUtils instance = null;

	/**
	 * 双重校验锁
	 * java5以后有效
	 * @return
	 */
	public static synchronized HttpClientUtils getInstance() {
		if (instance == null) {
			synchronized (HttpClientUtils.class) {
				if (instance == null) {
					instance = new HttpClientUtils();
				}
			}
		}
		return instance;
	}

	private static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);

	private static final MultiThreadedHttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
	public static final HttpClient httpClient = new HttpClient(httpConnectionManager);

	private static final MultiThreadedHttpConnectionManager httpConnectionManagerNoTimeOut = new MultiThreadedHttpConnectionManager();
	public static final HttpClient httpClientNoTimeOut = new HttpClient(httpConnectionManagerNoTimeOut);

	static {
		// 每主机最大连接数和总共最大连接数，通过hosfConfiguration设置host来区分每个主机
		httpClient.getHttpConnectionManager().getParams().setDefaultMaxConnectionsPerHost(100);
		httpClient.getHttpConnectionManager().getParams().setMaxTotalConnections(500);
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
		httpClient.getHttpConnectionManager().getParams().setSoTimeout(5000);
		httpClient.getHttpConnectionManager().getParams().setTcpNoDelay(true);
		httpClient.getHttpConnectionManager().getParams().setLinger(1000);
		// 失败的情况下会进行3次尝试,成功之后不会再尝试
		httpClient.getHttpConnectionManager().getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());

		// 每主机最大连接数和总共最大连接数，通过hosfConfiguration设置host来区分每个主机
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setDefaultMaxConnectionsPerHost(100);
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setMaxTotalConnections(500);
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setSoTimeout(0); // 设置永不超时
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setTcpNoDelay(true);
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setLinger(1000);
		// 失败的情况下会进行3次尝试,成功之后不会再尝试
		httpClientNoTimeOut.getHttpConnectionManager().getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
	}

	/**
	 * 执行5秒超时的http方法
	 * 失败的情况自动尝试3次
	 * @param httpMethod
	 * @return
	 * @throws URIException
	 */
	public int executeMethod(HttpMethod httpMethod) throws URIException {
		int result = 0;
		try {
			result = httpClient.executeMethod(httpMethod);
		} catch (HttpException e) {
			log.error(httpMethod.getURI() + ":" + e.getMessage());
		} catch (IOException e) {
			log.error(httpMethod.getURI() + ":" + e.getMessage());
		}
		return result;
	}

	/**
	 * 执行不超时的Http方法
	 * 
	 * @param httpMethod
	 * @return
	 * @throws URIException
	 */
	public int executeMethodNoTimeOut(HttpMethod httpMethod) throws URIException {
		int result = 0;
		try {
			result = httpClientNoTimeOut.executeMethod(httpMethod);
		} catch (HttpException e) {
			log.error(httpMethod.getURI() + ":" + e.getMessage());
		} catch (IOException e) {
			log.error(httpMethod.getURI() + ":" + e.getMessage());
		}
		return result;
	}
}
